#include <linux/crc32.h>

#include "rxe.h"
#include "rxe_loc.h"


int rxe_icrc_init(struct rxe_dev *rxe)
{
    struct crypto_shash *tfm;

    tfm = crypto_alloc_shash("crc32", 0, 0);
    if(IS_ERR(tfm)) {
        pr_warn("failed to init crc32 algorithm err:%ld\n",
               PTR_ERR(tfm));
        return PTR_ERR(tfm);
    }
    rxe->tfm = tfm;
    return 0;
}

static __be32 rxe_crc32(struct rxe_dev *rxe, __be32 crc, void *next, size_t len)
{
    __be32 icrc;
    int err;

    SHASH_DESC_ON_STACK(shash, rxe->tfm);
    shash->tfm = rxe->tfm;
    *(__be32 *)shash_desc_ctx(shash) = crc;
    err = crypto_shash_update(shash, next, len);
    if (unlikely(err)) {
        pr_warn_ratelimited("failed crc calculation, err: %d\n", err);
        return (__force __be32)crc32_le((__force u32)crc, next, len);
    }
    icrc = *(__be32 *)shash_desc_ctx(shash);
    barrier_data(shash_desc_ctx(shash));
    return icrc;
}

u32 rxe_icrc_hdr(struct rxe_pkt_info *pkt, struct sk_buff *skb)
{
    unsigned int bth_offset = 0;
    struct iphdr *ip4h = NULL;
    struct ipv6hdr *ip6h = NULL;
    struct rxe_bth *bth;
    int crc, length, hdr_size;


    hdr_size =


    return crc;
}

int rxe_icrc_check(struct sk_buff *skb, struct rxe_pkt_info *pkt)
{
    __be32 *icrcp;
    __be32 pkt_icrc, icrc;





}


void rxe_icrc_generate(struct sk_buff *skb, struct rxe_pkt_info *pkt)
{
    __be32 *icrcp;
    __be32 icrc;

    /*指向数据包ICRC的位置*/
    icrcp = (__be32 *)(pkt->hdr + pkt->paylen - RXE_ICRC_SIZE);
    /*对数据包头做校验*/
    icrc = rxe_icrc_hdr(skb, pkt);
    /*对数据部分做检验*/
    icrc = rxe_crc32(pkt->rxe, icrc, (u8*)payload_addr(pkt),
                    payload_size(pkt) + bth_pad(pkt));
    *icrcp = ~icrc;
    /*最终的icrc值*/
    printk("icrcp = %x\n", *icrcp);
}
